<template>
  <div class="min-h-screen py-8 px-4 sm:px-6 lg:px-8">
    <div class="max-w-4xl mx-auto">
      <!-- 页面标题 -->
      <div class="text-center mb-12">
        <h1 class="text-4xl font-bold mb-4 tech-text">Beacon API</h1>
        <p class="text-gray-300 text-lg">
          可靠地发送少量数据到服务器，即使在页面卸载时也能保证数据传输
        </p>
      </div>

      <!-- 浏览器支持提示 -->
      <div v-if="!isSupported" class="tech-card mb-8 border-yellow-600">
        <div class="flex items-center mb-4">
          <i class="i-carbon-warning text-yellow-500 text-xl mr-3"></i>
          <h3 class="text-xl font-semibold text-yellow-500">浏览器支持提示</h3>
        </div>
        <p class="text-gray-300 mb-4">
          您的浏览器不支持 Beacon API。此功能需要 Chrome 39+, Firefox 31+, Safari 11.1+ 或其他现代浏览器。
        </p>
        <p class="text-gray-400 text-sm">
          注意：Beacon API 主要用于在页面卸载时发送数据，如用户行为统计等。
        </p>
      </div>

      <!-- Beacon 发送演示 -->
      <div class="tech-card mb-8">
        <h2 class="text-2xl font-semibold mb-6 text-white">Beacon 数据发送</h2>
        
        <div class="space-y-6">
          <!-- 基本发送 -->
          <div class="bg-gray-800 rounded-lg p-6">
            <h3 class="text-lg font-semibold text-white mb-4">基本数据发送</h3>
            <div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-4">
              <div>
                <label class="block text-gray-300 mb-2">目标URL:</label>
                <input
                  v-model="basicBeacon.url"
                  type="url"
                  placeholder="https://httpbin.org/post"
                  class="w-full bg-gray-700 text-white border border-gray-600 rounded-lg px-3 py-2"
                >
              </div>
              <div>
                <label class="block text-gray-300 mb-2">数据内容:</label>
                <input
                  v-model="basicBeacon.data"
                  type="text"
                  placeholder="Hello Beacon API"
                  class="w-full bg-gray-700 text-white border border-gray-600 rounded-lg px-3 py-2"
                >
              </div>
            </div>
            <button
              @click="sendBasicBeacon"
              :disabled="!isSupported || !basicBeacon.url.trim()"
              class="tech-button disabled:opacity-50 disabled:cursor-not-allowed"
            >
              <i class="i-carbon-send mr-2"></i>
              发送 Beacon
            </button>
          </div>

          <!-- JSON 数据发送 -->
          <div class="bg-gray-800 rounded-lg p-6">
            <h3 class="text-lg font-semibold text-white mb-4">JSON 数据发送</h3>
            <div class="mb-4">
              <label class="block text-gray-300 mb-2">JSON 数据:</label>
              <textarea
                v-model="jsonBeacon.data"
                rows="4"
                placeholder='{"event": "page_view", "timestamp": 1234567890, "user_id": "user123"}'
                class="w-full bg-gray-700 text-white border border-gray-600 rounded-lg px-3 py-2 font-mono text-sm"
              ></textarea>
            </div>
            <div class="flex gap-4">
              <button
                @click="sendJsonBeacon"
                :disabled="!isSupported || !isValidJson"
                class="tech-button disabled:opacity-50 disabled:cursor-not-allowed"
              >
                <i class="i-carbon-document mr-2"></i>
                发送 JSON Beacon
              </button>
              <button
                @click="formatJson"
                class="bg-blue-600 hover:bg-blue-700 text-white px-4 py-2 rounded-lg transition-colors"
              >
                <i class="i-carbon-code mr-2"></i>
                格式化 JSON
              </button>
            </div>
          </div>

          <!-- FormData 发送 -->
          <div class="bg-gray-800 rounded-lg p-6">
            <h3 class="text-lg font-semibold text-white mb-4">FormData 发送</h3>
            <div class="space-y-4 mb-4">
              <div
                v-for="(field, index) in formFields"
                :key="index"
                class="flex gap-3 items-end"
              >
                <div class="flex-1">
                  <label class="block text-gray-300 mb-1 text-sm">字段名:</label>
                  <input
                    v-model="field.key"
                    type="text"
                    placeholder="field_name"
                    class="w-full bg-gray-700 text-white border border-gray-600 rounded-lg px-3 py-2"
                  >
                </div>
                <div class="flex-1">
                  <label class="block text-gray-300 mb-1 text-sm">字段值:</label>
                  <input
                    v-model="field.value"
                    type="text"
                    placeholder="field_value"
                    class="w-full bg-gray-700 text-white border border-gray-600 rounded-lg px-3 py-2"
                  >
                </div>
                <button
                  @click="removeFormField(index)"
                  class="bg-red-600 hover:bg-red-700 text-white px-3 py-2 rounded-lg transition-colors"
                >
                  <i class="i-carbon-trash-can"></i>
                </button>
              </div>
            </div>
            <div class="flex gap-4">
              <button
                @click="addFormField"
                class="bg-green-600 hover:bg-green-700 text-white px-4 py-2 rounded-lg transition-colors"
              >
                <i class="i-carbon-add mr-2"></i>
                添加字段
              </button>
              <button
                @click="sendFormBeacon"
                :disabled="!isSupported || formFields.length === 0"
                class="tech-button disabled:opacity-50 disabled:cursor-not-allowed"
              >
                <i class="i-carbon-form mr-2"></i>
                发送 FormData Beacon
              </button>
            </div>
          </div>
        </div>
      </div>

      <!-- 页面卸载演示 -->
      <div class="tech-card mb-8">
        <h3 class="text-xl font-semibold mb-6 text-white">页面卸载时发送数据</h3>
        
        <div class="bg-gray-800 rounded-lg p-6">
          <div class="mb-4">
            <h4 class="text-lg font-semibold text-white mb-3">用户行为统计</h4>
            <div class="grid grid-cols-2 md:grid-cols-4 gap-4 text-center">
              <div class="bg-gray-900 rounded-lg p-4">
                <div class="text-2xl font-bold text-tech-accent">{{ userStats.pageViews }}</div>
                <div class="text-gray-400 text-sm">页面浏览</div>
              </div>
              <div class="bg-gray-900 rounded-lg p-4">
                <div class="text-2xl font-bold text-green-400">{{ userStats.clicks }}</div>
                <div class="text-gray-400 text-sm">点击次数</div>
              </div>
              <div class="bg-gray-900 rounded-lg p-4">
                <div class="text-2xl font-bold text-blue-400">{{ formatTime(userStats.timeOnPage) }}</div>
                <div class="text-gray-400 text-sm">停留时间</div>
              </div>
              <div class="bg-gray-900 rounded-lg p-4">
                <div class="text-2xl font-bold text-purple-400">{{ userStats.scrollDepth }}%</div>
                <div class="text-gray-400 text-sm">滚动深度</div>
              </div>
            </div>
          </div>

          <div class="mb-4">
            <label class="flex items-center text-gray-300">
              <input
                v-model="enableUnloadBeacon"
                type="checkbox"
                class="mr-2"
              >
              启用页面卸载时自动发送统计数据
            </label>
          </div>

          <div class="flex gap-4">
            <button
              @click="simulatePageUnload"
              :disabled="!isSupported"
              class="tech-button disabled:opacity-50 disabled:cursor-not-allowed"
            >
              <i class="i-carbon-exit mr-2"></i>
              模拟页面卸载
            </button>
            <button
              @click="resetStats"
              class="bg-orange-600 hover:bg-orange-700 text-white px-4 py-2 rounded-lg transition-colors"
            >
              <i class="i-carbon-reset mr-2"></i>
              重置统计
            </button>
          </div>
        </div>
      </div>

      <!-- 预设场景演示 -->
      <div class="tech-card mb-8">
        <h3 class="text-xl font-semibold mb-6 text-white">常见使用场景</h3>
        
        <div class="grid grid-cols-1 md:grid-cols-2 gap-6">
          <!-- 用户行为分析 -->
          <div class="bg-gray-800 rounded-lg p-6">
            <h4 class="text-lg font-semibold text-white mb-4 flex items-center">
              <i class="i-carbon-analytics text-blue-400 mr-3"></i>
              用户行为分析
            </h4>
            <p class="text-gray-300 text-sm mb-4">发送用户在页面上的行为数据</p>
            <button
              @click="sendAnalyticsBeacon"
              :disabled="!isSupported"
              class="bg-blue-600 hover:bg-blue-700 disabled:bg-gray-600 disabled:cursor-not-allowed text-white px-4 py-2 rounded-lg transition-colors w-full"
            >
              <i class="i-carbon-chart-line mr-2"></i>
              发送分析数据
            </button>
          </div>

          <!-- 错误报告 -->
          <div class="bg-gray-800 rounded-lg p-6">
            <h4 class="text-lg font-semibold text-white mb-4 flex items-center">
              <i class="i-carbon-warning text-red-400 mr-3"></i>
              错误报告
            </h4>
            <p class="text-gray-300 text-sm mb-4">发送JavaScript错误和异常信息</p>
            <button
              @click="sendErrorBeacon"
              :disabled="!isSupported"
              class="bg-red-600 hover:bg-red-700 disabled:bg-gray-600 disabled:cursor-not-allowed text-white px-4 py-2 rounded-lg transition-colors w-full"
            >
              <i class="i-carbon-debug mr-2"></i>
              发送错误报告
            </button>
          </div>

          <!-- 性能监控 -->
          <div class="bg-gray-800 rounded-lg p-6">
            <h4 class="text-lg font-semibold text-white mb-4 flex items-center">
              <i class="i-carbon-dashboard text-green-400 mr-3"></i>
              性能监控
            </h4>
            <p class="text-gray-300 text-sm mb-4">发送页面加载和性能指标</p>
            <button
              @click="sendPerformanceBeacon"
              :disabled="!isSupported"
              class="bg-green-600 hover:bg-green-700 disabled:bg-gray-600 disabled:cursor-not-allowed text-white px-4 py-2 rounded-lg transition-colors w-full"
            >
              <i class="i-carbon-meter mr-2"></i>
              发送性能数据
            </button>
          </div>

          <!-- A/B测试结果 -->
          <div class="bg-gray-800 rounded-lg p-6">
            <h4 class="text-lg font-semibold text-white mb-4 flex items-center">
              <i class="i-carbon-test-tool text-purple-400 mr-3"></i>
              A/B测试结果
            </h4>
            <p class="text-gray-300 text-sm mb-4">发送A/B测试的用户行为结果</p>
            <button
              @click="sendABTestBeacon"
              :disabled="!isSupported"
              class="bg-purple-600 hover:bg-purple-700 disabled:bg-gray-600 disabled:cursor-not-allowed text-white px-4 py-2 rounded-lg transition-colors w-full"
            >
              <i class="i-carbon-experiment mr-2"></i>
              发送测试结果
            </button>
          </div>
        </div>
      </div>

      <!-- 发送历史 -->
      <div v-if="beaconHistory.length > 0" class="tech-card mb-8">
        <h3 class="text-xl font-semibold mb-4 text-white">发送历史</h3>
        
        <div class="space-y-3 max-h-64 overflow-y-auto">
          <div
            v-for="(record, index) in beaconHistory.slice().reverse()"
            :key="index"
            class="bg-gray-800 rounded-lg p-4"
          >
            <div class="flex justify-between items-start mb-2">
              <div class="flex items-center gap-3">
                <span :class="record.success ? 'text-green-400' : 'text-red-400'" class="text-sm font-semibold">
                  {{ record.success ? '✓ 成功' : '✗ 失败' }}
                </span>
                <span class="text-gray-400 text-sm">{{ record.type }}</span>
              </div>
              <span class="text-gray-400 text-sm">{{ formatTimestamp(record.timestamp) }}</span>
            </div>
            <div class="text-gray-300 text-sm">
              <strong>URL:</strong> {{ record.url }}
            </div>
            <div class="text-gray-300 text-sm mt-1">
              <strong>数据:</strong> {{ record.dataPreview }}
            </div>
          </div>
        </div>
        
        <div class="mt-4 pt-4 border-t border-gray-700">
          <button
            @click="clearHistory"
            class="bg-red-600 hover:bg-red-700 text-white px-4 py-2 rounded-lg transition-colors text-sm"
          >
            <i class="i-carbon-trash-can mr-1"></i>
            清空历史
          </button>
        </div>
      </div>

      <!-- 错误信息 -->
      <div v-if="error" class="tech-card border-red-600 mb-8">
        <div class="flex items-center mb-2">
          <i class="i-carbon-warning text-red-500 text-xl mr-3"></i>
          <h3 class="text-xl font-semibold text-red-500">错误</h3>
        </div>
        <p class="text-gray-300">{{ error }}</p>
      </div>

      <!-- API 信息 -->
      <div class="tech-card">
        <h3 class="text-xl font-semibold mb-4 text-white">API 信息</h3>
        <div class="space-y-4 text-gray-300">
          <div>
            <h4 class="font-semibold text-tech-accent mb-2">浏览器支持</h4>
            <p>Chrome 39+, Firefox 31+, Safari 11.1+, Edge 14+</p>
          </div>
          <div>
            <h4 class="font-semibold text-tech-accent mb-2">主要方法</h4>
            <ul class="list-disc list-inside space-y-1">
              <li><code class="bg-gray-800 px-2 py-1 rounded">navigator.sendBeacon(url, data)</code> - 发送数据</li>
              <li>支持的数据类型: String, Blob, ArrayBuffer, FormData</li>
              <li>返回布尔值表示是否成功排队发送</li>
            </ul>
          </div>
          <div>
            <h4 class="font-semibold text-tech-accent mb-2">主要特点</h4>
            <ul class="list-disc list-inside space-y-1">
              <li>异步发送，不阻塞页面卸载</li>
              <li>浏览器保证在页面卸载时发送数据</li>
              <li>数据大小限制通常为64KB</li>
              <li>使用POST方法发送数据</li>
            </ul>
          </div>
          <div>
            <h4 class="font-semibold text-tech-accent mb-2">使用场景</h4>
            <ul class="list-disc list-inside space-y-1">
              <li>用户行为统计和分析</li>
              <li>页面性能监控数据上报</li>
              <li>错误日志和异常报告</li>
              <li>A/B测试结果收集</li>
            </ul>
          </div>
          <div>
            <h4 class="font-semibold text-tech-accent mb-2">最佳实践</h4>
            <ul class="list-disc list-inside space-y-1">
              <li>在beforeunload或unload事件中使用</li>
              <li>数据应该尽可能小和精简</li>
              <li>服务器应该快速响应请求</li>
              <li>考虑用户隐私和数据保护</li>
            </ul>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, onMounted, onUnmounted } from 'vue'

// 类型定义
interface BeaconRecord {
  url: string
  type: string
  dataPreview: string
  success: boolean
  timestamp: number
}

interface FormField {
  key: string
  value: string
}

interface UserStats {
  pageViews: number
  clicks: number
  timeOnPage: number
  scrollDepth: number
}

// 响应式状态
const isSupported = ref(false)
const enableUnloadBeacon = ref(true)
const error = ref('')
const beaconHistory = ref<BeaconRecord[]>([])

// Beacon 配置
const basicBeacon = ref({
  url: 'https://httpbin.org/post',
  data: 'Hello Beacon API'
})

const jsonBeacon = ref({
  data: JSON.stringify({
    event: 'page_view',
    timestamp: Date.now(),
    user_id: 'user123',
    page_url: window.location.href
  }, null, 2)
})

const formFields = ref<FormField[]>([
  { key: 'event', value: 'form_submit' },
  { key: 'timestamp', value: Date.now().toString() }
])

// 用户统计
const userStats = ref<UserStats>({
  pageViews: 1,
  clicks: 0,
  timeOnPage: 0,
  scrollDepth: 0
})

// 页面加载时间
let pageLoadTime = Date.now()
let statsInterval: ReturnType<typeof setInterval> | null = null

// 计算属性
const isValidJson = computed(() => {
  try {
    JSON.parse(jsonBeacon.value.data)
    return true
  } catch {
    return false
  }
})

// 初始化
onMounted(() => {
  checkSupport()
  initializeTracking()
  startStatsTracking()
})

// 清理资源
onUnmounted(() => {
  if (statsInterval) {
    clearInterval(statsInterval)
  }
  
  if (enableUnloadBeacon.value && isSupported.value) {
    sendUnloadBeacon()
  }
})

// 检查浏览器支持
const checkSupport = () => {
  isSupported.value = 'sendBeacon' in navigator
}

// 初始化跟踪
const initializeTracking = () => {
  // 点击跟踪
  document.addEventListener('click', () => {
    userStats.value.clicks++
  })
  
  // 滚动跟踪
  document.addEventListener('scroll', updateScrollDepth)
  
  // 页面卸载跟踪
  window.addEventListener('beforeunload', handleBeforeUnload)
}

// 开始统计跟踪
const startStatsTracking = () => {
  statsInterval = setInterval(() => {
    userStats.value.timeOnPage = Math.floor((Date.now() - pageLoadTime) / 1000)
  }, 1000)
}

// 更新滚动深度
const updateScrollDepth = () => {
  const scrollTop = window.pageYOffset || document.documentElement.scrollTop
  const documentHeight = document.documentElement.scrollHeight - window.innerHeight
  const scrollPercentage = Math.round((scrollTop / documentHeight) * 100)
  
  userStats.value.scrollDepth = Math.max(userStats.value.scrollDepth, scrollPercentage || 0)
}

// 处理页面卸载前
const handleBeforeUnload = () => {
  if (enableUnloadBeacon.value && isSupported.value) {
    sendUnloadBeacon()
  }
}

// 发送基本 Beacon
const sendBasicBeacon = () => {
  const success = sendBeacon(
    basicBeacon.value.url,
    basicBeacon.value.data,
    'text'
  )
  
  addToHistory(
    basicBeacon.value.url,
    'Basic Text',
    basicBeacon.value.data,
    success
  )
}

// 发送 JSON Beacon
const sendJsonBeacon = () => {
  if (!isValidJson.value) {
    error.value = 'JSON 格式无效'
    return
  }
  
  const blob = new Blob([jsonBeacon.value.data], { type: 'application/json' })
  const success = sendBeacon(basicBeacon.value.url, blob, 'json')
  
  addToHistory(
    basicBeacon.value.url,
    'JSON',
    jsonBeacon.value.data.substring(0, 100) + '...',
    success
  )
}

// 发送 FormData Beacon
const sendFormBeacon = () => {
  const formData = new FormData()
  
  formFields.value.forEach(field => {
    if (field.key.trim() && field.value.trim()) {
      formData.append(field.key, field.value)
    }
  })
  
  const success = sendBeacon(basicBeacon.value.url, formData, 'form')
  
  const dataPreview = formFields.value
    .map(f => `${f.key}=${f.value}`)
    .join(', ')
  
  addToHistory(
    basicBeacon.value.url,
    'FormData',
    dataPreview,
    success
  )
}

// 通用 Beacon 发送方法
const sendBeacon = (url: string, data: any, type: string): boolean => {
  try {
    error.value = ''
    
    if (!isSupported.value) {
      throw new Error('浏览器不支持 Beacon API')
    }
    
    const success = navigator.sendBeacon(url, data)
    
    if (!success) {
      error.value = 'Beacon 发送失败，可能是数据过大或网络问题'
    }
    
    return success
  } catch (err) {
    console.error('发送 Beacon 失败:', err)
    error.value = err instanceof Error ? err.message : '发送 Beacon 失败'
    return false
  }
}

// 发送分析数据
const sendAnalyticsBeacon = () => {
  const analyticsData = {
    event: 'user_analytics',
    page_url: window.location.href,
    user_agent: navigator.userAgent,
    timestamp: Date.now(),
    stats: userStats.value
  }
  
  const success = sendBeacon(
    basicBeacon.value.url,
    JSON.stringify(analyticsData),
    'analytics'
  )
  
  addToHistory(
    basicBeacon.value.url,
    'Analytics',
    'User behavior analytics data',
    success
  )
}

// 发送错误报告
const sendErrorBeacon = () => {
  const errorData = {
    event: 'javascript_error',
    error_message: 'Sample error message',
    error_stack: 'Error stack trace...',
    page_url: window.location.href,
    timestamp: Date.now(),
    user_agent: navigator.userAgent
  }
  
  const success = sendBeacon(
    basicBeacon.value.url,
    JSON.stringify(errorData),
    'error'
  )
  
  addToHistory(
    basicBeacon.value.url,
    'Error Report',
    'JavaScript error report',
    success
  )
}

// 发送性能数据
const sendPerformanceBeacon = () => {
  const performanceData = {
    event: 'performance_metrics',
    page_load_time: Date.now() - pageLoadTime,
    dom_ready: performance.timing?.domContentLoadedEventEnd - performance.timing?.navigationStart || 0,
    page_url: window.location.href,
    timestamp: Date.now()
  }
  
  const success = sendBeacon(
    basicBeacon.value.url,
    JSON.stringify(performanceData),
    'performance'
  )
  
  addToHistory(
    basicBeacon.value.url,
    'Performance',
    'Page performance metrics',
    success
  )
}

// 发送 A/B 测试结果
const sendABTestBeacon = () => {
  const abTestData = {
    event: 'ab_test_result',
    test_id: 'homepage_layout_test',
    variant: 'variant_b',
    conversion: Math.random() > 0.5,
    timestamp: Date.now(),
    user_stats: userStats.value
  }
  
  const success = sendBeacon(
    basicBeacon.value.url,
    JSON.stringify(abTestData),
    'ab_test'
  )
  
  addToHistory(
    basicBeacon.value.url,
    'A/B Test',
    'A/B test result data',
    success
  )
}

// 发送页面卸载数据
const sendUnloadBeacon = () => {
  const unloadData = {
    event: 'page_unload',
    session_duration: Date.now() - pageLoadTime,
    final_stats: userStats.value,
    page_url: window.location.href,
    timestamp: Date.now()
  }
  
  const success = sendBeacon(
    basicBeacon.value.url,
    JSON.stringify(unloadData),
    'unload'
  )
  
  addToHistory(
    basicBeacon.value.url,
    'Page Unload',
    'Page unload statistics',
    success
  )
}

// 模拟页面卸载
const simulatePageUnload = () => {
  sendUnloadBeacon()
}

// 添加表单字段
const addFormField = () => {
  formFields.value.push({ key: '', value: '' })
}

// 移除表单字段
const removeFormField = (index: number) => {
  formFields.value.splice(index, 1)
}

// 格式化 JSON
const formatJson = () => {
  try {
    const parsed = JSON.parse(jsonBeacon.value.data)
    jsonBeacon.value.data = JSON.stringify(parsed, null, 2)
    error.value = ''
  } catch (err) {
    error.value = 'JSON 格式无效，无法格式化'
  }
}

// 重置统计
const resetStats = () => {
  userStats.value = {
    pageViews: 1,
    clicks: 0,
    timeOnPage: 0,
    scrollDepth: 0
  }
  pageLoadTime = Date.now()
}

// 添加到历史记录
const addToHistory = (url: string, type: string, dataPreview: string, success: boolean) => {
  beaconHistory.value.push({
    url,
    type,
    dataPreview,
    success,
    timestamp: Date.now()
  })
  
  // 只保留最近20条记录
  if (beaconHistory.value.length > 20) {
    beaconHistory.value.splice(0, beaconHistory.value.length - 20)
  }
}

// 清空历史记录
const clearHistory = () => {
  beaconHistory.value = []
}

// 格式化时间
const formatTime = (seconds: number): string => {
  const mins = Math.floor(seconds / 60)
  const secs = seconds % 60
  return `${mins}:${secs.toString().padStart(2, '0')}`
}

// 格式化时间戳
const formatTimestamp = (timestamp: number): string => {
  return new Date(timestamp).toLocaleTimeString('zh-CN')
}
</script>
